﻿#define _CRT_SECURE_NO_WARNINGS 1
//堆 ---小堆
//堆排序---基于堆的数据结构
//真堆排序----借助堆思想
//TopK问题-----找出N个数据中前K个最大值
#include"Heap.h"

void test()
{
	Heap hp;
	HPInit(&hp);
	HPPush(&hp, 3);
	HPPush(&hp, 2);
	HPPush(&hp, 1);
	HPPush(&hp, 5);

	//排序---小堆，升序
	while (!HPEmpty(&hp))
	{
		printf("%d ", HPTop(&hp));
		HPPop(&hp);
	}

	HPDesTroy(&hp);
}

//伪堆排序---基于堆的数据结构
//升序---小堆，降序----大堆
void test2()
{
	int arr[] = { 10, 25, 31, 13, 9, 5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	//建堆
	Heap hp;
	HPInit(&hp);
	//将数组中的数据传入堆中
	for (i = 0; i < sz; i++)
	{
		HPPush(&hp, arr[i]);
	}
	//取堆顶传入数组中
	i = 0;
	while (!HPEmpty(&hp))
	{
		arr[i++] = HPTop(&hp);
		HPPop(&hp);
	}
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

//真堆排序----借助堆思想
//升序---大堆，降序----小堆
void HeapSort(int* arr, int n)
{
	int i = 0;
	//向下调整算法建堆----O(n * log n)
	for (i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(arr, n , i); 
	}
	//向上调整算法建堆O(n)
	for (i = 1; i < n; i++)
	{
		AdjustUp(arr, i);
	}

	int end = n - 1;
	while (end)
	{
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, end, 0);
		end--;
	}
}

void test3()
{
	int arr[] = { 10, 25, 31, 13, 9, 5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	HeapSort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

void CreateNDate()
{
	//造数据
	int n = 100000;
	srand(time(0));
	const char* file = "data.txt";
	FILE* fin = fopen(file, "w");
	if (fin == NULL)
	{
		perror("fopen error"); return;
	}
	for (int i = 0; i < n; ++i)
	{
		int x = (rand() + i) % 1000000;

		fprintf(fin, "%d\n", x);
	}
	fclose(fin);
}
 
//TopK问题-----找出N个数据中前K个最大值
//前k个最⼤的元素，则建⼩堆
//前k个最⼩的元素，则建⼤堆
void TopK()
{
	int k = 0;
	printf("请输入k:");
	scanf("%d", &k);

	const char* file = "data.txt";
	FILE* fout = fopen(file, "r");
	if (fout == NULL)
	{
		perror("fopen fail");
		exit(1);
	}

	int* minHeap = (int*)malloc(sizeof(int) * k);
	if (minHeap == NULL)
	{
		perror("malloc fail");
		exit(2);
	}
	int i = 0;
	for (i = 0; i < k; i++)
	{
		fscanf(fout, "%d", &minHeap[i]);
	}
	//建k个数据的小堆
	for (i = (k - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(minHeap, k, i);
	}
	int x = 0;
	while (fscanf(fout, "%d", &x) != EOF)
	{
		//读取剩余数据，⽐堆顶的值⼤，就替换他进堆
		if (x > minHeap[0])
		{
			minHeap[0] = x;
			AdjustDown(minHeap, k, 0);
		}
	}

	for (i = 0; i < k; i++)
	{
		printf("%d ", minHeap[i]);
	}
	fclose(fout);
}
 

int main()
{
	//test();
	//test2();
	//test3();
	//test4();
	//CreateNDate();
	//TopK();
	return 0;
}